﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Press.MVC.Data.DataAccess.SqlServer;
using System.Collections;

namespace Press.MVC.Data
{
    public class SqlBlogRepository : IBlogRepository 
    {
        LinqBlogDataContext _db;

        public SqlBlogRepository()
        { }

        public SqlBlogRepository(LinqBlogDataContext dataContext)
        {
            _db = dataContext;
        }

        public IQueryable<Blog> GetBlogs()
        {
            var result = from b in _db.Blogs
                     let postcategories = GetPostCategories(b.BlogID)
                     let posts = GetPostsByBlog(b.BlogID)        
                     
                select new Blog
                {
                    ID = b.BlogID,
                    Name = b.Title,
                    SubTitle = b.SubTitle,
                    ShortName = b.ShortName,
                    IsActive = b.Active,
                    Settings = b.Settings,
                    PostCategories = new LazyList<PostCategory>(postcategories),
                    Posts = new LazyList<Post>(posts),
                    
                };

                return result;
        }

        public void SaveBlog(Blog blog)
        {
            using (LinqBlogDataContext db = new LinqBlogDataContext())
            {
                Press.MVC.Data.DataAccess.SqlServer.Blog bo;

                if (blog.ID > 0)
                {
                    bo = (from b in db.Blogs
                          where b.BlogID == blog.ID
                          select b).SingleOrDefault() ?? new Press.MVC.Data.DataAccess.SqlServer.Blog();
                }
                else
                {
                    bo = new Press.MVC.Data.DataAccess.SqlServer.Blog();
                }

                bo.ShortName = blog.ShortName;
                bo.Title = blog.Name;
                bo.SubTitle = blog.SubTitle;
                bo.Active = blog.IsActive;

                if (bo.BlogID == 0)
                    db.Blogs.InsertOnSubmit(bo);

                db.SubmitChanges();

                blog.ID = bo.BlogID;
            }
        }
       

        public IQueryable<Post> GetPosts()
        {
            var result = from p in _db.Posts
                         let comments = GetPostComments(p.PostID)
                 select new Post
                 {
                     ID = p.PostID,
                     Title = p.Title,
                     Summary = p.Summary,
                     Timestamp = p.Timestamp.Value,
                     BlogId = p.BlogId,
                     Body = p.Body,
                     AllowComments = p.AllowComments.Value,
                     PostCategoryID = p.PostCategoryID,
                     PostComments = new LazyList<PostComment>(comments)                     
                 };

            return result;
        }

        public IQueryable<PostComment> GetPostComments()
        {
            var result = from pc in _db.Comments
                 select new PostComment
                 {
                     ID = pc.CommentID,
                     PostID = pc.PostID,
                     Author = pc.Author,
                     Body = pc.Body
                 };

            return result;
        }

        public IQueryable<PostCategory> GetPostCategories()
        {
            var result = from pcat in _db.PostCategories
                         let posts = GetPostsByCategory(pcat.PostCategoryID)
                 select new PostCategory 
                 { 
                     ID = pcat.PostCategoryID,
                     Name = pcat.Name,
                     Posts = new LazyList<Post>(posts),
                     BlogId = pcat.BlogID
                 };
            return result;
        }

        public IQueryable<PostComment> GetPostComments(int postId)
        {
            var result = from pc in GetPostComments()
                         where pc.PostID == postId
                         select pc;
            return result;
        }

        public IQueryable<PostCategory> GetPostCategories(int blogId)
        {
            var result = from pcat in GetPostCategories()
                         where pcat.BlogId == blogId
                         select pcat;
            return result;
        }

        public IQueryable<Post> GetPostsByCategory(int postCategoryId)
        {
            var result = from post in GetPosts()
                         where post.PostCategoryID == postCategoryId
                         select post;
            return result;
        }

        public IQueryable<Post> GetPostsByBlog(int blogId)
        {
            var result = from post in GetPosts()
                         where post.BlogId == blogId
                         select post;
            return result;
        }

        // Need Test case
        public void SavePost(Post post)
        {
            using (LinqBlogDataContext db = new LinqBlogDataContext())
            {
                Press.MVC.Data.DataAccess.SqlServer.Post po;
                
                if (post.ID > 0)
                {
                    po = (from p in db.Posts
                           where p.PostID == post.ID
                          select p).SingleOrDefault() ?? new Press.MVC.Data.DataAccess.SqlServer.Post();
                }
                else
                {
                    po = new Press.MVC.Data.DataAccess.SqlServer.Post();
                }

                po.Title = post.Title;
                po.Summary = post.Summary;
                po.Body = post.Body;
                po.BlogId = post.BlogId;
                po.AllowComments = post.AllowComments;
                po.Timestamp = post.Timestamp;
                po.PostCategoryID = post.PostCategoryID;

                if (po.PostID == 0)
                    db.Posts.InsertOnSubmit(po);
                
                db.SubmitChanges();

                post.ID = po.PostID;
            }
        }

        public void DeletePost(int postId)
        {   
            using (LinqBlogDataContext db = new LinqBlogDataContext())
            {

                // Post
                var deletePost = from p in db.Posts
                                 where p.PostID == postId
                                 select p;
                
                // PostComment
                var deletePostComment = from pc in db.Comments
                                        where pc.PostID == postId
                                        select pc;

                db.Comments.DeleteAllOnSubmit(deletePostComment);                
                db.Posts.DeleteAllOnSubmit(deletePost);

                db.SubmitChanges();                
            }
        }

        public void SavePostCategory(PostCategory postCategory)
        {
            using (LinqBlogDataContext db = new LinqBlogDataContext())
            {
                Press.MVC.Data.DataAccess.SqlServer.PostCategory pc;

                if (postCategory.ID > 0)
                {
                    pc = (from pcc in db.PostCategories
                          where pcc.PostCategoryID == postCategory.ID
                          select pcc).SingleOrDefault() ?? new Press.MVC.Data.DataAccess.SqlServer.PostCategory();
                }
                else
                {
                    pc = new Press.MVC.Data.DataAccess.SqlServer.PostCategory();
                }

                pc.Name = postCategory.Name;
                pc.BlogID = postCategory.BlogId;
                
                if (pc.PostCategoryID == 0)
                    db.PostCategories.InsertOnSubmit(pc);

                db.SubmitChanges();

                postCategory.ID = pc.PostCategoryID;
            }
        }

        public void SavePostComment(PostComment postComment)
        {
            using (LinqBlogDataContext db = new LinqBlogDataContext())
            {
                Press.MVC.Data.DataAccess.SqlServer.Comment pc;

                if (postComment.ID > 0)
                {
                    pc = (from postcomment in _db.Comments
                          where postcomment.CommentID == postComment.ID
                          select postcomment).SingleOrDefault() ?? new Press.MVC.Data.DataAccess.SqlServer.Comment();
                }
                else
                {
                    pc = new Press.MVC.Data.DataAccess.SqlServer.Comment();
                }

                pc.PostID = postComment.PostID;
                pc.Author = postComment.Author;
                pc.Body = postComment.Body;
                pc.Timestamp = postComment.CreatedOn;
                pc.Email = postComment.Email;
                pc.Title = postComment.Title;

                if (pc.CommentID == 0)
                    db.Comments.InsertOnSubmit(pc);

                db.SubmitChanges();

                postComment.ID = pc.CommentID;
            }
        }
    }
}
